﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.ComponentModel;
using System.Collections.Generic;

namespace DraggableWindow
{
    [TemplatePart(Name = ModalPopupWindow.ModalMaskElement, Type = typeof(Rectangle))]
    [TemplateVisualState(Name = ModalPopupWindow.ModalStateModal, GroupName = ModalPopupWindow.ModalStateGroup )]
    [TemplateVisualState(Name = ModalPopupWindow.ModalStateNormal, GroupName = ModalPopupWindow.ModalStateGroup)]
    public class ModalPopupWindow : PopupWindow
    {
        private const string ModalMaskElement = "ModalMask";
        protected Rectangle ModalMask;


        protected const string ModalStateGroup = "ModalStates";
        protected const string ModalStateNormal = "Normal";
        protected const string ModalStateModal = "Modal";

        
        #region Constructor
        public ModalPopupWindow() :this(false)
		{
         	
			                  
		}
        public ModalPopupWindow(bool isOpen)
            : base(isOpen)
        {
            this.DefaultStyleKey = typeof(ModalPopupWindow);
		
        }
		#endregion

        public void Show(DependencyObject owner)
        {
            this.Dispatcher.BeginInvoke(() =>
            {
                ShowWindow(owner);
            });

        }

        #region Properties

        #endregion

        protected override void OnShowWindow(DependencyObject owner)
        {
            base.OnShowWindow(owner);
            ShowMask(owner);
            
        }

        protected override void OnHideWindow()
        {
            base.OnHideWindow();
            HideMask();
        }

        #region private stuff

        private void HideMask()
        {
            if ( this.ModalMask != null )
            {

                ReparentMask( this.ModalMask);
                this.ModalMask.Dispatcher.BeginInvoke(() =>
                {
                    VisualStateManager.GoToState(this, ModalPopupWindow.ModalStateNormal, true);
                });
                DecrementZIndex();
            }
        }

        void ShowMask()
        {
            ShowMask(this.Parent);
        }
        void ShowMask(DependencyObject owner)
        {
            if ( this.ModalMask != null )
            {
                
                Panel p = owner as Panel;
                if ( p != null )
                {
                    Grid g = p as Grid;
                    if ( g != null )
                    {
                        if ( g.ColumnDefinitions.Count > 1 )
                            ModalMask.SetValue(Grid.ColumnSpanProperty, g.ColumnDefinitions.Count);
                        if ( g.RowDefinitions.Count > 1 )
                            ModalMask.SetValue(Grid.RowSpanProperty, g.RowDefinitions.Count);
                    }
                    DeparentMask(p, this.ModalMask);
                    IncrementZIndex();
                    
                    this.ModalMask.Dispatcher.BeginInvoke(() =>
                    {
                        VisualStateManager.GoToState(this, ModalPopupWindow.ModalStateModal, true);
                    });
                }
                

            }
        }


        private void IncrementZIndex()
        {
            ModalMask.SetValue(Canvas.ZIndexProperty, DragDropControl.MaxZIndex);
            DragDropControl.MaxZIndex++;
            this.SetValue(Canvas.ZIndexProperty, DragDropControl.MaxZIndex);
            DragDropControl.MaxZIndex++;
        }
        private void DeparentMask(Panel parent, FrameworkElement control)
        {
            if ( control.Parent == this.Root )
            {
                this.Root.Dispatcher.BeginInvoke(() =>
                {
                   
                    this.Root.Children.Remove(control);
                    control.Dispatcher.BeginInvoke(() =>
                    {
                        parent.Children.Add(control);
                    });
                });
                
               
            }
        }
        private void ReparentMask( FrameworkElement control)
        {
            if ( control.Parent != this.Root  )
            {
                Panel p = control.Parent as Panel;
                if ( p != null )
                {
                    p.Children.Remove(control);
                    this.Root.Children.Add(control);
                }
            }
        }
        private void DecrementZIndex()
        {
            //ModalMask.SetValue(Canvas.ZIndexProperty, DragDropControl.MaxZIndex);
            //DragDropControl.MaxZIndex--;
            //this.SetValue(Canvas.ZIndexProperty, DragDropControl.MaxZIndex);
            //DragDropControl.MaxZIndex--;
        }
        #endregion

        public override void OnApplyTemplate()
        {
            
          
            // always get the mask
            ModalMask = GetTemplateChild(ModalMaskElement) as Rectangle;
            base.OnApplyTemplate();
          
        }


    }
}
